/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ar.com.arkios.kfconsap.rfc;

import ar.com.arkios.kfconsap.excepciones.DataTypeInvalidConversionException;
import ar.com.arkios.kfconsap.excepciones.RFCNotFoundException;
import ar.com.arkios.kfconsap.excepciones.SapComunicationException;
import ar.com.arkios.kfconsap.excepciones.SapGeneralException;
import ar.com.arkios.kfconsap.excepciones.TableNotFoundException;
import ar.com.arkios.kfconsap.conexion.SAPConnection;
import com.sap.mw.jco.IFunctionTemplate;

import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.Function;
import java.io.IOException;
import org.apache.log4j.Logger;

/**
 *
 * @author Ale
 * @version 1.01
 * Clase Abstracta GenericRFC
 */
public abstract class GenericRFC {
    
    /**
     * atriburos:
     * rfcName contiene el nombre de la RFC
     * myFunction contiene la funcion a ejecutar de la RFC.
     * myConnection guarda la referencia de la conexion tipo SAPConnection.
     * tieneParametrosRFC indica si la rfc tiene que realizar un filtro de busqueda.
     */
    private String rfcName;;
    private Function myFunction;
    private SAPConnection myConnection;
    private boolean tieneParametrosRFC;
    private String fieldParam;
    private String valueParam;
    private static final Logger myLogger = Logger.getLogger(GenericRFC.class);
    

    /**
     * Constructor obtiene referencia a la conexion tipo SAPConnection.
     * @throws java.io.IOException
     */
    public GenericRFC() throws SapGeneralException{
        try{
            this.myConnection = SAPConnection.getInstance();
            if(!(this.myConnection.getConnection().isAlive())){ 
                myLogger.error("La conexion No estava viva, se intentará abrir.");
                this.myConnection.open();
                myLogger.error("La Reconexion o Conexión fue exitosa.");
            }else{
                myLogger.error("La conexion continua viva, no se intenta reconectar.");
            }
        }catch(SapComunicationException ex){
            throw new SapGeneralException(ex.getMessage());            
        }
        
    }
    
    /**
     * Devuelve la funcion actual de la RFC.
     * @return Function
     */
    protected Function getMyFunction() {
        return myFunction;
    }

    /**
     * Permite que las clases que heredan puedan setear su funcion.
     * @param myFunction
     */
    protected void setMyFunction(Function myFunction) {
        this.myFunction = myFunction;
    }

    /**
     * Devuelve a las clases hijas el nombre de la RFC.
     * @return String
     */
    protected String getRfcName() {
        return rfcName;
    }

    /**
     * Recibe de las clases que heredan el nombre de la RFC
     * @param rfcName
     */
    protected void setRfcName(String rfcName) {
        this.rfcName = rfcName;
    }
    
    /**
     * Crea la funcion a raiz de un nombre de RFC recibido.
     * @param name
     * @throws java.lang.Exception
     */
    protected void createFunction(String name) throws RFCNotFoundException{
       try {
            IFunctionTemplate ft = this.myConnection.getMyRepository().getFunctionTemplate (name.toUpperCase ());
            if (ft == null){
                this.myFunction = null;
            }else{                                
                this.myFunction = ft.getFunction();
                if(this.isParametrosRFC()){
                    this.myFunction.getImportParameterList().setValue(this.getValueParam(),this.getFieldParam());
                }
            }                
            
        }catch (JCO.Exception ex) {
            throw new RFCNotFoundException("RFC: "+name);
        }
    }
    
     /**
     * Crea la funcion a tomando como nombre de la funcion el nombre de la RFC.
     * @throws java.lang.Exception
     */
    protected void createFunction() throws RFCNotFoundException{
        this.createFunction(this.getRfcName());
    }
    
    /**
     * Ejecuta la funcion RFC
     */
    public void executeFunction() throws SapGeneralException{
        myConnection.getConnection().execute((Function)this.myFunction);
        try {
            this.loadTables();
        } catch (DataTypeInvalidConversionException ex) {
            throw new SapGeneralException(ex.getMessage());
        } catch (TableNotFoundException ex) {
            throw new SapGeneralException(ex.getMessage());
        }
    }
    
    /**
     * Metodo que debe estar sobreescrito en las clases que heredan de esta.
     */
    public abstract void loadTables() throws DataTypeInvalidConversionException, TableNotFoundException;

    /**
     * Devuelve la referencia a la conexion del tipo SAPConnection
     * @return SAPConnection
     */
    public SAPConnection getMyConnection() {
        return myConnection;
    }

    /**
     * Setea la conexion del tipo SAPConnection
     * @param myConnection
     */
    protected void setMyConnection(SAPConnection myConnection) {
        this.myConnection = myConnection;
    }

    /**
     * Devuelve true si la RFC utiliza parametros de Filtro
     * @return boolean
     */
    public boolean isParametrosRFC() {
        return tieneParametrosRFC;
    }

    /**
     * Setea el atruibuto tieneParametrosRFC segun tenga o no filtros.
     * true = Tiene parametros
     * false = No tiene Parametros.
     * @param tieneParametrosConexion
     */
    public void setTieneParametrosRFC(boolean tieneParametrosConexion) {
        this.tieneParametrosRFC = tieneParametrosConexion;
    }

    private String getFieldParam() {
        return fieldParam;
    }

    protected void setFieldParam(String fieldParam) {
        this.fieldParam = fieldParam;
    }

    private String getValueParam() {
        return valueParam;
    }

    protected void setValueParam(String valueParam) {
        this.valueParam = valueParam;
    }


  
    

}
